package com.seafood.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * 地址位置信息实体类
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "location_addresses")
public class LocationAddress extends BaseEntity {
    
    @NotBlank(message = "地址名称不能为空")
    @Column(name = "address_name", nullable = false, length = 200)
    private String addressName;
    
    @Column(name = "province", length = 50)
    private String province;
    
    @Column(name = "city", length = 50)
    private String city;
    
    @Column(name = "district", length = 50)
    private String district;
    
    @NotBlank(message = "详细地址不能为空")
    @Column(name = "detailed_address", nullable = false, length = 500)
    private String detailedAddress;
    
    @Column(name = "postal_code", length = 10)
    private String postalCode;
    
    @NotNull(message = "纬度不能为空")
    @DecimalMin(value = "-90.0", message = "纬度范围为-90到90")
    @DecimalMax(value = "90.0", message = "纬度范围为-90到90")
    @Column(name = "latitude", nullable = false, precision = 10, scale = 7)
    private BigDecimal latitude;
    
    @NotNull(message = "经度不能为空")
    @DecimalMin(value = "-180.0", message = "经度范围为-180到180")
    @DecimalMax(value = "180.0", message = "经度范围为-180到180")
    @Column(name = "longitude", nullable = false, precision = 10, scale = 7)
    private BigDecimal longitude;
    
    @NotNull(message = "地址类型不能为空")
    @Enumerated(EnumType.STRING)
    @Column(name = "address_type", nullable = false)
    private AddressType addressType;
    
    @Column(name = "business_id")
    private Long businessId;
    
    @Column(name = "contact_name", length = 100)
    private String contactName;
    
    @Column(name = "contact_phone", length = 20)
    private String contactPhone;
    
    @Column(name = "is_default")
    private Boolean isDefault = false;
    
    @Column(name = "is_active")
    private Boolean isActive = true;
    
    @Column(name = "address_tag", length = 50)
    private String addressTag; // 地址标签：家、公司、仓库等
    
    @Column(name = "remarks", length = 500)
    private String remarks;
    
    // 地理编码相关字段
    @Column(name = "country_code", length = 10)
    private String countryCode = "CN";
    
    @Column(name = "formatted_address", length = 1000)
    private String formattedAddress;
    
    @Column(name = "geocoding_accuracy")
    private Integer geocodingAccuracy; // 地理编码精度级别
    
    @Column(name = "geocoding_source", length = 50)
    private String geocodingSource; // 地理编码来源：baidu, amap, google等
    
    /**
     * 地址类型枚举
     */
    public enum AddressType {
        USER_HOME,          // 用户家庭地址
        USER_COMPANY,       // 用户公司地址
        SUPPLIER_LOCATION,  // 供应商地址
        WAREHOUSE,          // 仓库地址
        DELIVERY_ADDRESS,   // 配送地址
        PICKUP_POINT,       // 取货点
        COLD_CHAIN_STATION, // 冷链站点
        FISHING_AREA,       // 捕捞区域
        PROCESSING_PLANT,   // 加工厂
        MARKET,             // 市场
        OTHER               // 其他
    }
    
    /**
     * 获取完整地址字符串
     */
    public String getFullAddress() {
        StringBuilder sb = new StringBuilder();
        if (province != null) sb.append(province);
        if (city != null) sb.append(city);
        if (district != null) sb.append(district);
        if (detailedAddress != null) sb.append(detailedAddress);
        return sb.toString();
    }
    
    /**
     * 计算与另一个地址的距离（简单计算，实际应使用地理计算库）
     */
    public double calculateDistance(LocationAddress other) {
        if (other == null || other.getLatitude() == null || other.getLongitude() == null) {
            return -1;
        }
        
        double lat1 = this.latitude.doubleValue();
        double lon1 = this.longitude.doubleValue();
        double lat2 = other.latitude.doubleValue();
        double lon2 = other.longitude.doubleValue();
        
        // 简单的直线距离计算（实际应使用球面距离计算）
        double deltaLat = Math.toRadians(lat2 - lat1);
        double deltaLon = Math.toRadians(lon2 - lon1);
        
        double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
                   Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                   Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        
        // 地球半径（公里）
        double earthRadius = 6371;
        
        return earthRadius * c;
    }
}